#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

typedef std::vector<std::vector<int> > Tiles;
int rowLength;
int mtxSize;

bool ertelmes(int i,int j)
{
    return (0<=i && i<mtxSize/rowLength && 0<=j && j<rowLength);
}

int getTile(const Tiles& tiles, int i)
{
  if (0 > i || i >= mtxSize)
    return -1;
  else
    return tiles[i / rowLength][i % rowLength];
}



int getTile(const Tiles& tiles, int i, int j)
{
  if (!ertelmes(i, j))
    return -1;
  else
    return tiles[i][j];
}

bool connected(const Tiles& t,int type) {
    vector<vector<bool> > elerheto;
    elerheto.resize(mtxSize/rowLength);
    for(int i=0;i<mtxSize/rowLength;++i)
        elerheto[i].resize(rowLength,false);
    bool vege = false;
    for(int i=0;!vege;++i)
        if(getTile(t,i)==type) {
            elerheto[i/rowLength][i % rowLength]=true;
            vege = true;
        }

    bool valt=true;
    while(valt) {
        valt = false;
        for(int i=0;i<mtxSize/rowLength;++i)
        for(int j=0;j<rowLength;++j)
            if(!elerheto[i][j] && getTile(t,i,j)==type)
            {
                if(ertelmes(i,j-1) && elerheto[i][j-1]) {
                    elerheto[i][j]=true;
                    valt=true;
                }
                if(ertelmes(i,j+1) && elerheto[i][j+1]) {
                    elerheto[i][j]=true;
                    valt=true;
                }
                if(ertelmes(i-1,j) && elerheto[i-1][j]) {
                    elerheto[i][j]=true;
                    valt=true;
                }
                if(ertelmes(i+1,j) && elerheto[i+1][j]) {
                    elerheto[i][j]=true;
                    valt=true;
                }
            }
    }
    for(int i=0;i<mtxSize/rowLength;++i)
        for(int j=0;j<rowLength;++j)
            if(getTile(t,i,j)==type && !elerheto[i][j])
                return false;
    return true;
}

bool connected(const Tiles& t)
{
    return connected(t,0) && connected(t,1) && connected(t,2);
}

void showTiles(const Tiles& tiles, std::ostream& o = std::cout)
{
  o<<tiles.size()<<" "<<tiles[0].size()<<std::endl;
  for(int i=0;i<tiles.size();++i)
  {
    for(int j=0;j<tiles[i].size();++j)
      o<<tiles[i][j]<<" ";
    o<<std::endl;
  }
}

void beolvas(const std::string& filename, Tiles& tiles)
{
  std::ifstream be(filename.c_str());
  int n,m,tmp;
  be>>n>>m;
  tiles.resize(n);
  for(int i=0;i<n;++i)
  {
    tiles[i].resize(m);
    for(int j=0;j<m;++j)
    {
      be>>tmp;
      tiles[i][j]=tmp;
    }
  }
  be.close();
  mtxSize = n*m;
  rowLength = m;
}

void swap(Tiles& tiles, int a, int b, int c, int d)
{
  int tmp = tiles[a][b];
  tiles[a][b] = tiles[c][d];
  tiles[c][d] = tmp;
}

int main(int, char** argv)
{
	Tiles t;
  beolvas(argv[1], t);
  ifstream swaps(argv[2]);
  int noSwaps;
  swaps>>noSwaps;
  //showTiles(t);
  for(int i=0;i<noSwaps;++i)
  {
    int a,b,c,d;
    swaps>>a>>b>>c>>d;
    swap(t, a ,b, c , d);
    //showTiles(t);
  }
  swaps.close();
  cout<<connected(t)<<endl;
}